﻿using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.Configuration.Repository;
using Ocelot.DependencyInjection;
using Ocelot.DownstreamRouteFinder.Finder;
using Ocelot.Middleware;
using System;
using System.Linq;

namespace Ocelot.Extension
{
    public static class OcelotExtensions
    {

        public static IApplicationBuilder UseOcelotDefaultView(this IApplicationBuilder app)
        {
            app.MapWhen(context =>
            {
                var internalConfigurationResponse =
                    context.RequestServices.GetRequiredService<IInternalConfigurationRepository>().Get();

                if (internalConfigurationResponse.IsError || internalConfigurationResponse.Data.Routes.Count == 0)
                {
                    return false;
                }


                var internalConfiguration = internalConfigurationResponse.Data;
                var downstreamRouteFinder = context.RequestServices
                    .GetRequiredService<IDownstreamRouteProviderFactory>()
                    .Get(internalConfiguration);
                var response = downstreamRouteFinder.Get(context.Request.Path, context.Request.QueryString.ToString(),
                    context.Request.Method, internalConfiguration, context.Request.Host.ToString());

                return !response.IsError
                       && !string.IsNullOrEmpty(response.Data?.Route?.DownstreamRoute?.FirstOrDefault()
                           ?.DownstreamScheme);
            },

            async appBuilder => await appBuilder.UseOcelot());

            app.UseRouting();

            return app;
        }

        /// <summary>
        /// 更新Ocelot配置
        /// </summary>
        /// <param name="path">路由</param>
        /// <returns></returns>
        //public static IApplicationBuilder UseModifyConfiguration(this IApplicationBuilder app, string path = "/modify/configuration")
        //{

        //    app.Map(new PathString(path), appBuilder =>
        //    {
        //        appBuilder.Use(async (context, next) =>
        //        {
        //            // 这里应该做身份验证

        //            var configurationRepo = context.RequestServices.GetRequiredService<IFileConfigurationRepository>();
        //            var ocelotConfiguration = await configurationRepo.Get();
        //            if (!ocelotConfiguration.IsError)
        //            {
        //                var internalConfigurationRepo = context.RequestServices.GetRequiredService<IInternalConfigurationRepository>();
        //                var internalConfigurationCreator = context.RequestServices.GetRequiredService<IInternalConfigurationCreator>();
        //                var internalConfiguration = await internalConfigurationCreator.Create(ocelotConfiguration.Data);
        //                if (!internalConfiguration.IsError)
        //                {
        //                    internalConfigurationRepo.AddOrReplace(internalConfiguration.Data);
        //                    context.Response.StatusCode = 200;
        //                    return;
        //                }
        //                else
        //                {
        //                    throw new Exception($"update ocelot configuration error, error in create ocelot internal configuration, error messages:{string.Join(", ", ocelotConfiguration.Errors)}");
        //                }
        //            }
        //            else
        //            {
        //                throw new Exception($"update ocelot configuration error, error in get ocelot configuration from configurationRepo, error messages:{string.Join(", ", ocelotConfiguration.Errors)}");
        //            }
        //            context.Response.StatusCode = 500;
        //        });
        //    });

        //    return app;
        //}


        public static IOcelotBuilder StoreConfigurationInSqlserver(this IOcelotBuilder builder)
        {
            builder.Services.AddSingleton<IFileConfigurationRepository, SqlserverFileConfigurationRepository>();
            return builder;
        }

        public static IOcelotBuilder StoreConfigurationInSqlserver(this IOcelotBuilder builder, Action<SqlserverFileConfigurationOptions> optionsAction)
        {
            if (optionsAction != null)
            {
                builder.Services.Configure(optionsAction);
            }
            builder.StoreConfigurationInSqlserver();
            return builder;
        }
    }
}
